# -*- coding:utf-8 -*-

from utils.logger import get_logger
from utils.views import WdListCreateAPIView, WdRetrieveUpdateAPIView, WdDestroyAPIView, WdAPIView, WdListAPIView
from basic.models import ElevatorInfo, ElevatorPersonInfo, ElevatorStatistics, ThirdElevators, ElevatorFittings, \
    ElevatorFollowedByUser
from serializer import ElevatorListSerializer, ElevatorSerializer, ElevatorPersonListSerializer, \
    ElevatorPersonSerializer, ElevatorStatisticsListSerializer, ElevatorDetailSerializer, \
    ElevatorFittingsListSerializer, ElevatorFittingsSerializer, ElevatorFittingsDetailSerializer
from users.models import CompanyInfo, Person, CompanyPerson
from utils.response import general_json_response, ErrorCode
from rest_framework import status, views
from rest_framework.parsers import FileUploadParser
import hashlib
from django.db.models import Q
import operator
import datetime, time
from ElevatorAdmin.elevator_run_state import DEV_RUN_STATE
from manufacturer.models import StatusMsg, AuthorityCode, RepairContent, Manufacturer
from django.http import HttpResponse
import csv


logger = get_logger(__name__)


class ElevatorListCreateView(WdListCreateAPIView, WdDestroyAPIView):

    model = ElevatorInfo
    g_serializer_class = ElevatorListSerializer
    p_serializer_class = ElevatorSerializer
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True
    OBJECT_WITH_ACTIVE = True

    POST_CHECK_REQUEST_PARAMETER = ("elevator_name",
                                    "property_company", "elevator_property")
    # SEARCH_FIELDS = ("elevator_name", 'elevator_no', 'internal_no', 'factory_no', 'elevator_model',
    #                  'install_company', 'maintain_company_name')
    SEARCH_FIELDS = ('register_code', 'elevator_name', 'elevator_model', 'installation_company', 'product_company',
                     'internal_no')
    FILTER_FIELDS = ('elevator_type', 'usage_status', 'elevator_property', 'registry_status', 'is_binded',
                     'maintain_company', "property_company")
    FOREIGN_SEARCH_FIELD_MAP = {'property_company': [CompanyInfo, 'name'], 'maintain_company': [CompanyInfo, 'name']}
    # FILTER_FIELDS = ('province', 'city', 'country', 'usage_status', 'status', 'controller_status', 'camera_status')
    # DELETE_CHECK_REQUEST_PARAMETER = ('ele_ids',)

    def get_serializer_class(self):
        if self.request.method.lower() == "get":
            return self.g_serializer_class
        elif self.request.method.lower() == "post":
            return self.p_serializer_class

    def qs_filter(self, qs):
        qs = super(ElevatorListCreateView, self).qs_filter(qs)
        register = self.request.GET.get("register", None)
        if register == "1":
            qs = qs.filter(~Q(register_code=''), ~Q(register_code=None))
        user = self.request.user
        if user.role == 30:
            com = CompanyPerson.objects.filter_active(auth_user=user).first().company
            qs = qs.filter(property_company=com)
        elif user.role == 40:
            qs = qs.filter(supervised=1)
        is_online = self.request.GET.get("is_online", u"2")
        if is_online == u"1":
            register_codes = AuthorityCode.objects.filter_active(is_online=True).values_list("elevator_code", flat=True).distinct()
            return qs.filter(register_code__in=register_codes)
        elif is_online == u"0":
            register_codes = AuthorityCode.objects.filter_active(is_online=True).values_list("elevator_code", flat=True).distinct()
            return qs.exclude(register_code__in=register_codes)
        inspect = self.request.GET.get("inspect", None)
        today = datetime.date.today()
        next_month = today + datetime.timedelta(days=30)
        # 检验不合格
        if inspect == u"0":
            qs = qs.filter(inspection_conclusion__icontains=u"不合格")
        elif inspect == u"1":
            qs = qs.exclude(inspection_conclusion__icontains=u"不合格")
        # 即将过期
        elif inspect == u"2":
            qs = qs.filter(next_yearly_inspection_date__gte=today, next_yearly_inspection_date__lte=next_month)
        # 过期
        elif inspect == u"3":
            qs = qs.filter(next_yearly_inspection_date__lt=today)
        return qs

    def qs_filter_by_ele(self, qs):
        user = self.request.user
        if user.role == 0:
            return qs
        if user.role in [20, 30, 40] and user.company_person.is_admin:
            return qs
        codes = self.get_registers()
        print codes
        qs = qs.filter(register_code__in=codes)
        return qs

    def qs_search(self, qs):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        if key_words is None or not key_words:
            return qs
        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            search_sql.append(Q(**{"%s__icontains" % search_field: key_words}))
        search_sql += self.process_foreign_search()
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs

    def delete(self, request, *args, **kwargs):
        elevator_ids = self.request.data.get('ele_ids', [])
        for elevator_id in elevator_ids:
            instance = ElevatorInfo.objects.get(id=elevator_id)
            self.perform_destroy(instance)
        # ElevatorPersonInfo.objects.filter(elevator__in=elevator_ids).delete()
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)

    def perform_destroy(self, instance):
        if self.OBJECT_WITH_ACTIVE:
            instance.is_active = False
            instance.contract = None
            if hasattr(instance, 'last_modify_user_id'):
                instance.last_modify_user_id = self.request.user.id
            instance.save()
        else:
            instance.delete()

    def post_check_parameter(self, kwargs):
        code = super(ElevatorListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        register_code = self.request.data.get('register_code', None)
        if register_code:
            e = ElevatorInfo.objects.filter_active(register_code=register_code).first()
            if e:
                code = ErrorCode.REGISTER_CODE_EXISTED
        next_time = self.request.data.pop("next_time", None)
        if next_time:
            self.request.data.update({"next_yearly_inspection_date": next_time})
        maintain_company_id = self.request.data.get('maintain_company', None)
        if maintain_company_id:
            maintain_company = CompanyInfo.objects.get(id=maintain_company_id)
            self.request.data.update({'maintain_company_name': maintain_company.name})
        property_company_id = self.request.data.get('property_company', None)
        property_company = CompanyInfo.objects.get(id=property_company_id)
        self.request.data.update({'property_company_name': property_company.name})
        manufacturer_company = self.request.data.get("manufacturer_company", None)
        if manufacturer_company:
            mc = Manufacturer.objects.get(id=manufacturer_company)
            self.request.data.update({'manufacturer_company_name': mc.name})
        # self.request.data.update({'service_id': maintain_company_id})
        # use_company_id = self.request.data.get('use_company', None)
        # use_company = CompanyInfo.objects.get(id=use_company_id)
        # self.request.data.update({'use_company_name': use_company.name})
        # installation_company_id = self.request.data.get('installation_company', None)
        # if installation_company_id:
        # installation_company = CompanyInfo.objects.get(id=installation_company_id)
        # self.request.data.update({'installation_company_name': installation_company.name})
        return code

    def perform_create(self, serializer):
        super(ElevatorListCreateView, self).perform_create(serializer)
        elevator_id = serializer.data['id']
        elevator_obj = self.model.objects.get(id=elevator_id)
        elevator_id_str = str(elevator_id)
        md5 = hashlib.md5()
        md5.update(elevator_id_str.encode('utf-8'))
        qr_code = md5.hexdigest()
        elevator_obj.qr_code = qr_code
        elevator_obj.save()


class ElevatorListView(WdListCreateAPIView):
    model = ElevatorInfo
    serializer_class = ElevatorListSerializer
    QUERY_WITH_CONTRACT = True
    QUERY_WITH_ACTIVE = True

    def get_queryset(self):
        qs = self.model.objects.all()
        if self.QUERY_WITH_ACTIVE:
            qs = qs.filter(is_active=True)
        qs = self.qs_business_role(qs)
        qs = self.qs_filter(qs)
        qs = self.qs_search(qs)
        qs = self.qs_order_by(qs)
        qs = qs.filter(contract=None)
        return qs


class ElevatorRetrieveUpdateDestroyAPIView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True
    OBJECT_WITH_ACTIVE = True
    model = ElevatorInfo
    p_serializer_class = ElevatorSerializer
    g_serializer_class = ElevatorDetailSerializer
    # POST_CHECK_REQUEST_PARAMETER = ("elevator_name", "register_code", "maintain_company",
    #                                 "property_company", "elevator_property")

    def get_serializer_class(self):
        if self.request.method.lower() == "get":
            return self.g_serializer_class
        elif self.request.method.lower() == "put":
            return self.p_serializer_class

    def post_check_parameter(self, kwargs):
        code = super(ElevatorRetrieveUpdateDestroyAPIView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        register_code = self.request.data.get('register_code', None)
        obj = self.get_object()
        if register_code and register_code != obj.register_code:
            e = ElevatorInfo.objects.filter_active(register_code=register_code).first()
            if e:
                code = ErrorCode.REGISTER_CODE_EXISTED
                return code
        next_time = self.request.data.pop("next_time", None)
        if next_time:
            self.request.data.update({"next_yearly_inspection_date": next_time})
        maintain_company_id = self.request.data.get('maintain_company', None)
        if maintain_company_id:
            maintain_company = CompanyInfo.objects.get(id=maintain_company_id)
            self.request.data.update({'maintain_company_name': maintain_company.name})
        property_company_id = self.request.data.get('property_company', None)
        property_company = CompanyInfo.objects.get(id=property_company_id)
        self.request.data.update({'property_company_name': property_company.name})
        manufacturer_company = self.request.data.get("manufacturer_company", None)
        if manufacturer_company:
            mc = Manufacturer.objects.get(id=manufacturer_company)
            self.request.data.update({'manufacturer_company_name': mc.name})
        else:
            self.request.data.update({'manufacturer_company_name': None})
        return code

    def perform_destroy(self, instance):
        if self.OBJECT_WITH_ACTIVE:
            instance.is_active = False
            instance.contract = None
            if hasattr(instance, 'last_modify_user_id'):
                instance.last_modify_user_id = self.request.user.id
            instance.save()
        else:
            instance.delete()

    # def delete(self, request, *args, **kwargs):
    #     super(ElevatorRetrieveUpdateDestroyAPIView, self).delete(request, *args, **kwargs)
    #
    #     # obj = self.get_id()
    #     # ElevatorPersonInfo.objects.filter(elevator=obj).delete()
    #     return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class ElevatorFollowedView(WdAPIView):

    def post(self, request, *args, **kwargs):
        user = self.request.user
        pk = self.request.data.get("id", None)
        follow = self.request.data.get("follow", None)
        is_active = True if follow else False
        ElevatorFollowedByUser.objects.update_or_create(elevator_id=pk, user=user, defaults={"is_active": is_active})
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class ElevatorStatesPollingView(WdAPIView):

    def get(self, request, *args, **kwargs):
        elevator = self.request.GET.get("elevator", None)
        es = None
        if not elevator:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u"elevator 为必传字段")
        elevator = ElevatorInfo.objects.filter_active(id=elevator).first()
        if elevator:
            es = StatusMsg.objects.filter_active(authority_code__elevator_code=elevator.register_code).order_by("-id").first()
        if not es:
            es = StatusMsg.objects.filter_active(id=1).first()
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, es.get_elevator_status())


# class ElevatorPersonListCreateView(WdListCreateAPIView):
#     POST_CHECK_REQUEST_PARAMETER = ('elevator', 'workers')
#     SEARCH_FIELDS = ('elevator_name', 'register_code')
#     # FILTER_FIELDS = ('is_binded', )
#
#     """[{u'worker_type': 10, u'worker': [275, 273, 272]}, {u'worker_type': 20, u'worker': [274, 273]},
#      {u'worker_type': 30, u'worker': [273, 271]}]"""
#
#     def post(self, request, *args, **kwargs):
#         elevator = self.request.data.get('elevator', None)
#         workers = self.request.data.get('workers', None)
#         worker_list = []
#         for dic in workers:
#             for v in dic['worker']:
#                 worker_list.append({'worker_type': dic['worker_type'], 'worker': v})
#         e = ElevatorInfo.objects.get(id=elevator)
#         bulk_list = []
#         for item in worker_list:
#             worker = Person.objects.get(id=item['worker'])
#             ep = ElevatorPersonInfo(elevator=e, worker=worker, worker_type=item['worker_type'], service_id=e.service_id)
#             bulk_list.append(ep)
#         qs = ElevatorPersonInfo.objects.bulk_create(bulk_list)
#         e.is_binded = True
#         e.save()
#         data = ElevatorPersonSerializer(instance=qs, many=True).data
#         return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)
#
#     def get(self, request, *args, **kwargs):
#         user = self.request.user
#         if user.role == 0:
#             e_qs = ElevatorInfo.objects.filter_active()
#         elif user.role == 20:
#             e_qs = ElevatorInfo.objects.filter_active(service_id=user.company_person.company.id)
#         else:
#             e_qs = ElevatorInfo.objects.none()
#         is_binded = self.request.GET.get('is_binded', 2)
#         page = int(self.request.GET.get('page', 1))
#         page_by = int(self.request.GET.get('page_size_count', 10))
#         if is_binded == u'-1':
#             e_qs = e_qs.filter(is_binded=False)
#         elif is_binded == u'1':
#             e_qs = e_qs.filter(is_binded=True)
#         else:
#             pass
#         e_qs = self.qs_search(e_qs)
#         e_qs = self.qs_filter(e_qs)
#         count = e_qs.count()
#         ids = e_qs.values_list('id', flat=True).order_by('-id')[(page - 1) * page_by: page * page_by]
#         result = []
#         for i in ids:
#             e = ElevatorInfo.objects.get(id=i)
#             eps = ElevatorPersonInfo.objects.filter(elevator=i)
#             obj = {
#                      'elevator': i,
#                      'is_binded': e.is_binded,
#                      'register_code': e.register_code,
#                      'elevator_name': e.elevator_name,
#                      'register_status': eps.first().register_status if eps.exists() else 10,
#                      'worker': [
#                          {
#                              'worker_type': '10',
#                              'worker_person': [
#                                  ]
#                          },
#
#                          {
#                              'worker_type': '20',
#                              'worker_person': [
#                                  ]
#                          },
#
#                          {
#                              'worker_type': '30',
#                              'worker_person': [
#                                  ]
#                          }
#                      ]
#             }
#             for ep in eps:
#                 if ep.worker_type == 10:
#                     obj['worker'][0]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                               'work_id': ep.worker.id})
#                 elif ep.worker_type == 20:
#                     obj['worker'][1]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                               'work_id': ep.worker.id})
#                 else:
#                     obj['worker'][2]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                               'work_id': ep.worker.id})
#             result.append(obj)
#         return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, {'count': count, 'results': result})


# class ElevatorPersonDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
#
#     POST_CHECK_REQUEST_PARAMETER = ('elevator', 'workers')
#     GET_CHECK_REQUEST_PARAMETER = ('elevator', )
#     DELETE_CHECK_REQUEST_PARAMETER = ('elevator', )
#
#     """[{u'worker_type': 10, u'worker': [275, 273, 272]}, {u'worker_type': 20, u'worker': [274, 273]},
#          {u'worker_type': 30, u'worker': [273, 271]}]"""
#
#     def put(self, request, *args, **kwargs):
#         sql = []
#         sql_2 = []
#         elevator = self.request.data.get('elevator', None)
#         e = ElevatorInfo.objects.get(id=elevator)
#         for item in self.request.data.get('workers', []):
#             for v in item['worker']:
#                 p = Person.objects.get(id=v)
#                 sql.append(Q(**{'worker_type': item['worker_type'], 'worker': p, 'elevator': e, 'service_id': e.service_id}))
#                 sql_2.append({'worker_type': item['worker_type'], 'worker': p, 'elevator': e, 'service_id': e.service_id})
#         query = reduce(operator.or_, sql)
#         eps = ElevatorPersonInfo.objects.filter(elevator=elevator).exclude(query)
#         if eps.exists():
#             eps.delete()
#         for item in sql_2:
#             e_p = ElevatorPersonInfo.objects.filter(**item)
#             if e_p and len(e_p) > 1:
#                 e_p.delete()
#                 ElevatorPersonInfo.objects.create(**item)
#             elif e_p and len(e_p) == 1:
#                 continue
#             else:
#                 ElevatorPersonInfo.objects.create(**item)
#         qs = ElevatorPersonInfo.objects.filter(elevator=e)
#         data = ElevatorPersonSerializer(instance=qs).data
#         return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)
#
#     def delete(self, request, *args, **kwargs):
#         elevator = self.request.data.get('elevator', None)
#         eps = ElevatorPersonInfo.objects.filter(elevator=elevator)
#         eps.delete()
#         elevator = ElevatorInfo.objects.get(elevator=elevator)
#         elevator.is_binded = False
#         elevator.save()
#         return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)
#
#     def get(self, request, *args, **kwargs):
#         elevator = self.request.GET.get('elevator', None)
#         e = ElevatorInfo.objects.get(id=elevator)
#         e_p = ElevatorPersonInfo.objects.filter(elevator=e).first()
#         result = []
#         obj = {
#             'elevator': elevator,
#             'is_binded': e.is_binded,
#             'register_code': e.register_code,
#             'elevator_name': e.elevator_name,
#             'register_status': e_p.register_status if e_p else 10,
#             'worker': [
#                 {
#                     'worker_type': '10',
#                     'worker_person': [
#                     ]
#                 },
#
#                 {
#                     'worker_type': '20',
#                     'worker_person': [
#                     ]
#                 },
#
#                 {
#                     'worker_type': '30',
#                     'worker_person': [
#                     ]
#                 }
#             ]
#         }
#         eps = ElevatorPersonInfo.objects.filter(elevator=elevator)
#         for ep in eps:
#             if ep.worker_type == 10:
#                 obj['worker'][0]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                           'work_id': ep.worker.id})
#             elif ep.worker_type == 20:
#                 obj['worker'][1]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                           'work_id': ep.worker.id})
#             else:
#                 obj['worker'][2]['worker_person'].append({'work_name': ep.worker.auth_user.real_name,
#                                                           'work_id': ep.worker.id})
#         result.append(obj)
#         return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, result)


class ElevatorPersonListCreateView(WdListCreateAPIView):
    model = ElevatorInfo
    g_serializer_class = ElevatorPersonListSerializer
    p_serializer_class = None
    POST_DATA_RESPONSE = True
    SEARCH_FIELDS = ('register_code',)
    FILTER_FIELDS = ('is_binded',)
    FOREIGN_SEARCH_FIELD_MAP = {'property_company': [CompanyInfo, 'name'], 'maintain_company': [CompanyInfo, 'name']}

    def get_serializer_class(self):
        if self.request.method.lower() == "get":
            return self.g_serializer_class
        elif self.request.method.lower() == "post":
            return self.p_serializer_class

    # def qs_business_role(self, request, *args, **kwargs):
    #     user = self.request.user
    #     if user.role == 0:
    #         qs = ElevatorInfo.objects.filter_active(registry_status=20)
    #     elif user.role == 20:
    #         qs = ElevatorInfo.objects.filter_active(service_id=user.company_person.company.id, registry_status=20)
    #     return qs

    def qs_filter(self, qs):
        qs = super(ElevatorPersonListCreateView, self).qs_filter(qs)
        qs = qs.filter(registry_status=20)
        if self.request.user.role == 30:
            com = CompanyPerson.objects.filter_active(auth_user=self.request.user).first().company
            qs = qs.filter(property_company=com)
        elif self.request.user.role == 40:
            qs = qs.filter(supervised=1)
        return qs

    def qs_search(self, qs):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        if key_words is None or not key_words:
            return qs
        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            search_sql.append(Q(**{"%s__icontains" % search_field: key_words}))
        search_sql += self.process_foreign_search()
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs

    def qs_filter_by_ele(self, qs):
        user = self.request.user
        if user.role == 0:
            return qs
        if user.role in [20, 30, 40] and user.company_person.is_admin:
            return qs
        codes = self.get_registers()
        qs = qs.filter(register_code__in=codes)
        return qs


class ElevatorPersonDetailView(WdRetrieveUpdateAPIView):
    model = ElevatorInfo
    g_serializer_class = ElevatorPersonListSerializer
    p_serializer_class = ElevatorPersonSerializer
    POST_DATA_RESPONSE = True

    def get_serializer_class(self):
        if self.request.method.lower() == "get":
            return self.g_serializer_class
        elif self.request.method.lower() == "put":
            return self.p_serializer_class

    def post_check_parameter(self, kwargs):
        code = super(ElevatorPersonDetailView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        elevator_obj = self.get_object()
        elevator_id = self.get_object().id
        service_id = elevator_obj.service_id

        maintain_person_qs = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=10, status=10)
        if maintain_person_qs:
            old_maintain_person_ids = [obj.worker.id for obj in maintain_person_qs]
        else:
            old_maintain_person_ids = []

        rescue_person_qs = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=20, status=10)
        if rescue_person_qs:
            old_rescue_person_ids = [obj.worker.id for obj in rescue_person_qs]
        else:
            old_rescue_person_ids = []

        repair_person_qs = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=30, status=10)
        if repair_person_qs:
            old_repair_person_ids = [obj.worker.id for obj in repair_person_qs]
        else:
            old_repair_person_ids = []

        worker = self.request.data.pop('worker')
        maintain_person_ids = worker[0]['worker_person']
        rescue_person_ids = worker[1]['worker_person']
        repair_person_ids = worker[2]['worker_person']

        print maintain_person_ids

        # 更新维保人员
        if old_maintain_person_ids:
            print "old_maintain_person_ids %s: " % old_maintain_person_ids
            for old_person_id in old_maintain_person_ids:
                if old_person_id not in maintain_person_ids:
                    print "old_person_id %s" % old_person_id
                    maintain_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=10,
                                                                            worker=old_person_id).first()
                    maintain_person_obj.status = 20
                    maintain_person_obj.save()
                else:
                    maintain_person_ids.remove(old_person_id)
            print "maintain_person_ids: %s" % maintain_person_ids
            if maintain_person_ids:
                for new_person_id in maintain_person_ids:
                    new_person_obj = Person.objects.get(id=new_person_id)
                    elevator_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=10,
                                                                            worker=new_person_id).first()
                    if elevator_person_obj:
                        elevator_person_obj.status = 10
                        elevator_person_obj.is_new = True
                        elevator_person_obj.save()
                    else:
                        ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=10, worker=new_person_obj,
                                                          is_new=True, status=10, service_id=service_id)
            else:
                pass
        else:
            for new_person_id in maintain_person_ids:
                print "new_person_id: %s" % new_person_id
                new_person_obj = Person.objects.get(id=new_person_id)
                ep = ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=10, worker=new_person_obj,
                                                  is_new=True, status=10, service_id=service_id)
                print "ep.id: %s" % ep.id
                print ep

        # 更新救援人员
        if old_rescue_person_ids:
            for old_person_id in old_rescue_person_ids:
                if old_person_id not in rescue_person_ids:
                    rescue_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=20,
                                                                          worker=old_person_id).first()
                    rescue_person_obj.status = 20
                    rescue_person_obj.save()
                else:
                    rescue_person_ids.remove(old_person_id)
            if rescue_person_ids:
                for new_person_id in rescue_person_ids:
                    new_person_obj = Person.objects.get(id=new_person_id)
                    elevator_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=20,
                                                                            worker=new_person_id).first()
                    if elevator_person_obj:
                        elevator_person_obj.status = 10
                        elevator_person_obj.is_new = True
                        elevator_person_obj.save()
                    else:
                        ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=20, worker=new_person_obj,
                                                          is_new=True, status=10, service_id=service_id)
            else:
                pass
        else:
            for new_person_id in rescue_person_ids:
                new_person_obj = Person.objects.get(id=new_person_id)
                ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=20, worker=new_person_obj,
                                                  is_new=True, status=10, service_id=service_id)

        # 更新急修人员
        if old_repair_person_ids:
            for old_person_id in old_repair_person_ids:
                if old_person_id not in repair_person_ids:
                    repair_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=30,
                                                                          worker=old_person_id).first()
                    repair_person_obj.status = 20
                    repair_person_obj.save()
                else:
                    repair_person_ids.remove(old_person_id)
            if repair_person_ids:
                for new_person_id in repair_person_ids:
                    new_person_obj = Person.objects.get(id=new_person_id)
                    elevator_person_obj = ElevatorPersonInfo.objects.filter(elevator=elevator_id, worker_type=30,
                                                                            worker=new_person_id).first()
                    if elevator_person_obj:
                        elevator_person_obj.status = 10
                        elevator_person_obj.is_new = True
                        elevator_person_obj.save()
                    else:
                        ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=30, worker=new_person_obj,
                                                          is_new=True, status=10, service_id=service_id)
            else:
                pass
        else:
            for new_person_id in repair_person_ids:
                new_person_obj = Person.objects.get(id=new_person_id)
                ElevatorPersonInfo.objects.create(elevator=elevator_obj, worker_type=30, worker=new_person_obj,
                                                  is_new=True, status=10, service_id=service_id)
        return code


class ElevatorStatisticsListView(WdListAPIView):

    model = ElevatorStatistics
    serializer_class = ElevatorStatisticsListSerializer
    FILTER_FIELDS = ('month', 'company')
    GET_CHECK_REQUEST_PARAMETER = ('month', )

    def get_queryset(self):
        user = self.request.user
        qs = self.model.objects.all()
        qs = self.qs_business_role(qs)
        month = self.request.GET.get('month')
        company = self.request.GET.get('company')
        y, m = month.split('-')
        y, m = int(y), int(m)
        month = datetime.date(year=y, month=m, day=1)
        n_m = m + 1 if m < 12 else 1
        n_y = y + 1 if n_m == 1 else y
        next_month = datetime.date(year=n_y, month=n_m, day=1)
        if user.role == 20:
            qs = qs.filter(day__lt=next_month, day__gte=month).order_by('-numbers')[:1]
        elif user.role == 0 and not company:
            ids = []
            companys = CompanyInfo.objects.filter_active(company_type=100)
            for company in companys:
                company_obj = qs.filter(day__lt=next_month, day__gte=month, company=company).order_by('-numbers').first()
                if company_obj:
                    ids.append(company_obj.id)
            qs = qs.filter(id__in=ids)
        elif user.role == 0 and company:
            qs = qs.filter(day__lt=next_month, day__gte=month, company=company).order_by('-numbers')[:1]
        return qs


class ThirdElevatorsApiView(WdAPIView):

    def get(self, request):
        user = self.request.user
        if user.role != 0:
            return general_json_response(status.HTTP_200_OK, ErrorCode.PERMISSION_FAIL)
        count = ThirdElevators.objects.count()
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, count)


class ElevatorPersonBindListCreateView(WdListCreateAPIView):
    '''
    电梯批量绑定人员
    '''
    model = ElevatorPersonInfo
    serializer_class = ElevatorPersonListSerializer

    def post(self, request, *args, **kwargs):
        t = time.time()
        elevator_ids = self.request.data.get('elevator_ids')
        worker1_ids = self.request.data.get('worker1_ids')  # 维保人员
        worker2_ids = self.request.data.get('worker2_ids')  # 救援人员
        worker3_ids = self.request.data.get('worker3_ids')  # 急修人员
        if not elevator_ids:
            return general_json_response(status=status.HTTP_400_BAD_REQUEST, code=ErrorCode.INVALID_INPUT)
        obj_list = []
        for elevator_id in elevator_ids:
            elevator = ElevatorInfo.objects.filter(id=elevator_id)[0]
            if len(obj_list) >= 1000:
                try:
                    print('commit条数:%s' % len(obj_list))
                    ElevatorPersonInfo.objects.bulk_create(obj_list)
                except Exception as e:
                    print(e)
                finally:
                    del obj_list[:]
                    print(len(obj_list))

            # 绑定维保人员
            for worker1_id in worker1_ids:
                worker_type = 10
                try:
                    worker = Person.objects.filter(id=worker1_id)[0]
                    obj_list.append(ElevatorPersonInfo(elevator=elevator, worker=worker, worker_type=worker_type,service_id=worker.company_id))
                except Exception as e:
                    print("elevator_id:%s,worker1_id:%s,msg:%s" % (elevator_id, worker1_id, e))
                    continue
            # 绑定救援人员
            for worker2_id in worker2_ids:
                worker_type = 20
                try:
                    worker = Person.objects.filter(id=worker2_id)[0]
                    obj_list.append(ElevatorPersonInfo(elevator=elevator, worker=worker, worker_type=worker_type,service_id=worker.company_id))
                except Exception as e:
                    print("elevator_id:%s,worker1_id:%s,msg:%s" % (elevator_id, worker2_id, e))
                    continue
            # 绑定急修人员
            for worker3_id in worker3_ids:
                worker_type = 30
                try:
                    worker = Person.objects.filter(id=worker3_id)[0]
                    obj_list.append(ElevatorPersonInfo(elevator=elevator, worker=worker, worker_type=worker_type,service_id=worker.company_id))
                except Exception as e:
                    print("elevator_id:%s,worker1_id:%s,msg:%s" % (elevator_id, worker3_id, e))
                    continue
        try:
            print('内存创建条数:%s' % len(obj_list))
            ElevatorPersonInfo.objects.bulk_create(obj_list)
        except Exception as e:
            print(e)
        t1 = time.time()
        print("耗时:%s"%(t1-t))
        response = general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, {})
        return response


class QueryElevatorStatusView(WdAPIView):
    def get(self, request, *args, **kwargs):
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, DEV_RUN_STATE)


class QueryElevatorForRepair(WdAPIView):

    def get(self, request, *args, **kwargs):
        data = dict()
        user = self.request.user
        if user.role != 20:
            return general_json_response(status.HTTP_200_OK, ErrorCode.PERMISSION_FAIL, u"只有维保单位才可以创建维修工单")
        company = user.company_person.company
        register_codes = ElevatorInfo.objects.filter_active(service_id=company.id).\
            values("id", "register_code", "elevator_name", "internal_no", "elevator_type").distinct()
        data["elevators"] = list(register_codes)
        persons = Person.objects.filter_active(service_id=company.id)
        ps = list()
        for p in persons:
            ps.append({"id": p.id, "real_name": p.auth_user.real_name})
        data['users'] = ps
        data['maintain_company'] = [{"id": company.id, "name": company.name}]
        property_company = CompanyInfo.objects.filter_active(company_type=300, service_id=company.id).values("id", "name")
        data['property_company'] = list(property_company)
        qs = RepairContent.objects.filter_active(service_id__in=(company.id, 0))
        qs = [rc for rc in qs if rc.name() is not None and rc.costs() is not None]
        wb_contents = [rc.to_json() for rc in qs]
        data['content'] = wb_contents
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class ElevatorFittingsListCreateView(WdListCreateAPIView, WdDestroyAPIView):

    model = ElevatorFittings
    p_serializer_class = ElevatorFittingsSerializer
    serializer_class = ElevatorFittingsListSerializer
    SEARCH_FIELDS = ("register_code", )

    def post_check_parameter(self, kwargs):
        code = super(ElevatorFittingsListCreateView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        register_code = self.request.data.get("register_code", None)
        if register_code:
            ei = ElevatorInfo.objects.filter_active(register_code=register_code).first()
            if ei:
                self.request.data.update({"elevator": ei.id})
        return code

    def delete(self, request, *args, **kwargs):
        ids = self.request.data.get("ids", [])
        ElevatorFittings.objects.filter_active(id__in=ids).update(is_active=False)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)

    def qs_filter(self, qs):
        qs = super(ElevatorFittingsListCreateView, self).qs_filter(qs)
        user = self.request.user
        if user in (20, 30, 40) and not user.company_person.is_admin:
            codes = self.get_registers()
            qs = qs.filter(register_code__in=codes)
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        if time_from:
            qs = qs.filter(replace_time__gte=time_from)
        if time_to:
            qs = qs.filter(replace_time__lte=time_to)
        return qs


class ElevatorFittingsDetailView(WdRetrieveUpdateAPIView, WdDestroyAPIView):
    model = ElevatorFittings
    p_serializer_class = ElevatorFittingsSerializer
    serializer_class = ElevatorFittingsDetailSerializer

    def post_check_parameter(self, kwargs):
        code = super(ElevatorFittingsDetailView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        register_code = self.request.data.get("register_code", None)
        if register_code:
            ei = ElevatorInfo.objects.filter_active(register_code=register_code).first()
            if ei:
                self.request.data.update({"elevator": ei.id})
        return code


class ElevatorFittingsDownView(WdAPIView):

    def get_registers(self):
        u""" 非各个角色的管理员才会调用 """
        from users.models import OrganizationElevatorRelation, OrganizationAdminRoRelation, ElevatorAdminRoRelation, \
            AuthUserElevatorRelation
        user = self.request.user
        if user.permission_type == 20:
            codes = AuthUserElevatorRelation.objects.filter_active(auth_user=user).values_list("register_code", flat=True).distinct()
            return codes
        admin_role = user.admin_role
        codes = list()
        if not admin_role:
            return codes
        if admin_role.management_type == 20:
            codes = ElevatorAdminRoRelation.objects.filter_active(admin_role=admin_role).values_list("register_code", flat=True).distinct()
            return codes
        oarr = OrganizationAdminRoRelation.objects.filter_active(admin_role=admin_role).first()
        if not oarr:
            return codes
        org = oarr.organization
        if not org:
            return codes
        codes = OrganizationElevatorRelation.objects.filter_active(organization=org).values_list("register_code", flat=True).distinct()
        return codes

    def get(self, request, *args, **kwargs):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        l = [u'配件号', u'原配件号', u'电梯注册代码', u'配件名称', u'配件类型', u'更换时间', u'质保期限', u'更换人', u'更换方式']
        l = [i.encode('utf8') for i in l]
        writer.writerow(l)
        user = self.request.user
        qs = ElevatorFittings.objects.filter_active()
        if user.role in (20, 30, 40):
            qs = qs.filter(service_id=user.service_id)
            if not user.company_person.is_admin:
                codes = self.get_registers()
                qs = qs.filter(register_code__in=codes)
        for i in qs:
            m = [i.number, i.old_number, i.register_code, i.name, i.atype,
                 i.replace_time.strftime("%Y-%m-%d") if i.replace_time.strftime("%Y-%m-%d") else "",
                 i.warranty_time.strftime("%Y-%m-%d") if i.warranty_time.strftime("%Y-%m-%d") else "",
                 i.person_name(), i.replace_mode]
            m = [i.encode('utf8') for i in m]
            writer.writerow(m)
        return response


class ElevatorAndPersonForElevatorFittingsListView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        eis = ElevatorInfo.objects.filter_active()
        persons = Person.objects.filter_active()
        user = self.request.user
        role = user.role
        if role == 0:
            pass
        elif role == 10:
            eis = eis.none()
            persons = persons.none()
        else:
            eis = eis.filter(service_id=user.service_id)
            persons = persons.filter(service_id=user.service_id)
            if not user.company_person.is_admin:
                codes = self.get_registers()
                eis = eis.filter(register_code__in=codes)
        register_codes = eis.filter(register_code__isnull=False).values_list("register_code", flat=True).distinct()
        l = []
        for p in persons:
            l.append({
                "person": p.id,
                "name": p.auth_user.real_name if p.auth_user else ""
            })
        data = {"persons": l, "register_codes": register_codes}
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)





























